﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.ComponentModel;

namespace CaptchaControl
{
    public class CaptchaControl : System.Web.UI.WebControls.WebControl,
        IPostBackDataHandler, INamingContainer, IValidator

    {
        #region Public Properties 

        [DefaultValue(50), 
         Description("Specify the height of the captcha image"),
         Category("Appearance")]
        public int DrawHeight { get; set; }

        [DefaultValue(200),
         Description("Specify the width of the captcha image"),
         Category("Appearance")]
        public int DrawWidth { get; set; }

        [DefaultValue(50),
         Description("Number of characters to be printed"),
         Category("Appearance")]
        public int NumberOfChars { get; set; }

        [Description("States the validation state of the user. True if validated else false"),
         Category("Properties")]
        public bool IsValidated { get { return _isValidated; } }


        [DefaultValue(""),
         Description("Class Name"),
         Category("Appearance")]
        public string ClassStyleName { get; set; }

        [DefaultValue(20),
         Description("Tamaño de la caja de texto"),
         Category("Appearance")]
        public int SizeText { get; set; }


        [DefaultValue(60),
         Description("Tiempo en cache del Captcha"),
         Category("Properties")]
        public double AbsoluteExpiration { get; set; }

        #endregion

        #region Private Variables
        
        private bool _isValidated = false;
        private CaptchaImage _captcha = new CaptchaImage();
        private string _previousGUID = string.Empty;
        
        #endregion

        #region WebControl Members

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write("<div classname = '" + ClassStyleName + "'>");
            writer.Write("<img src=\"CaptchaImage.aspx?guid="+ _captcha.UniqueID + "\"></div>");
            writer.Write("<div style='height: 7px;'></div>");
            writer.Write("<div><input name=\'" + this.UniqueID + "\' size='" + SizeText.ToString() + "'  type=text autocomplete=off></div>");
        }


        //protected override void Render(System.Web.UI.HtmlTextWriter writer)
        //{
        //    writer.Write("<div classname = '" + ClassStyleName + "'><table>");
        //    writer.Write("<tr><td><img src=\"CaptchaImage.aspx?guid=" + _captcha.UniqueID + "\"></tr></td>");
        //    writer.Write("<tr><td><input name=\"" + this.UniqueID + "\" type=text></tr></td>");
        //    writer.Write("</table></div>");
        //}

        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresControlState(this);
            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (this.Visible)
            {
                GenerateCaptcha();
            }
            base.OnPreRender(e);
        }

        protected override void LoadControlState(object savedState)
        {
            if (savedState != null)
            {
                _previousGUID = savedState.ToString();
            }
        }

        protected override object SaveControlState()
        {
            return _captcha.UniqueID;
        }

        #endregion

        #region Captcha Members

        private void GenerateCaptcha()
        {
            _captcha.DrawHeight = this.DrawHeight;
            _captcha.DrawWidth = this.DrawWidth;
            _captcha.NumberOfChars = this.NumberOfChars;

            HttpRuntime.Cache.Add(_captcha.UniqueID, _captcha, null, DateTime.Now.AddSeconds(this.AbsoluteExpiration),
                   TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
        }

        private CaptchaImage GetCaptchaFromCache(string guid)
        {
            return (CaptchaImage)HttpRuntime.Cache.Get(guid);
        }

        private void RemoveCaptchaFromCache(string guid)
        {
            HttpRuntime.Cache.Remove(guid);
        }

        private void ValidateCaptcha(string data)
        {
            CaptchaImage captcha = GetCaptchaFromCache(_previousGUID);
            if (captcha != null)
            {
                _isValidated = (captcha.CaptchaCode.ToUpper() == data.ToUpper());
                if (_isValidated)
                {
                    this.ErrorMessage = "Invalid code entered";
                }
            }
            RemoveCaptchaFromCache(_previousGUID);
           
        }

        #endregion

        #region IPostBackDataHandler Members

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            ValidateCaptcha(postCollection[this.UniqueID].ToString());
            return false;
        }

        public void RaisePostDataChangedEvent()
        {
            
        }

        #endregion

        #region IValidator Members

        public string ErrorMessage
        {
            get;
            set;
        }

        public bool IsValid
        {
            get
            {
                return _isValidated;
            }
            set
            {
            }
        }

        public void Validate()
        {
        }

        #endregion
    }
}
